﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace LWH.ByteProtocol
{
    /// <summary>
    /// 骨架属性类，提供AbstractProperty最基本的实现
    /// </summary>
    public abstract class SkeletalProperty : AbstractProperty
    {

        /// <summary>
        /// 在父属性中的序号
        /// </summary>
        private int mIndex;

        /// <summary>
        /// 直接存放自己的属性，也就是父节点
        /// </summary>
        private OwnerProperty mOwnerProperty;


        protected SkeletalProperty(OwnerProperty ownerProperty)
        {

            mOwnerProperty = ownerProperty;
        }

        #region Override AbstractProperty Method


        protected internal override void setIndex(int index)
        {
            mIndex = index;
        }

        public override int getIndex()
        {
            return mIndex;
        }


        protected internal override OwnerProperty getOwnerProperty()
        {
            return mOwnerProperty;
        }

        /// <summary>
        /// 获取在OwnerProperty的byte数组中的起始位置
        /// </summary>
        /// <returns></returns>
        protected internal override int getOwnerOffset()
        {
            return mOwnerProperty.getPropertyOffset(this);
        }


        /// <summary>
        /// 获取存放Protocol数据的byte数组
        /// </summary>
        /// <returns></returns>
        protected internal override byte[] getSrcData()
        {
            return mOwnerProperty.getSrcData();
        }
        #endregion

        #region Override IProperty Method


        /// <summary>
        ///一般情况下不需要重写此方法
        ///默认情况下起始位置会根据属性在列表中的位置和各个属性的长度自动计算，但是在对性能有特殊需求
        ///并且在明确确定重写此方法能对性能需求有帮助的情况下，可以重写此方法并根据协议返回一个期望值
        /// <returns>属性在byte数组中的起始位置</returns>
        public override int getOffset()
        {
            return mOwnerProperty.getOffset() + getOwnerOffset();
        }


        public override byte[] getData()
        {
            int offset = getOffset();
            byte[] srcData = getSrcData();
            int length = getLength();

            if (srcData == null || srcData.Length < offset + length)
            {
                return null;
            }

            return ByteConverter.copyOfRange(srcData, offset, offset + length);
        }


        public override void setData(byte[] data, int offset, int length)
        {
            byte[] srcData = getSrcData();
            if (srcData != null)
            {
                Buffer.BlockCopy(data, offset, srcData, getOffset(), length);
            }
        }


        public override bool handleProperty(Dictionary<String, Object> context)
        {
            return true;
        }

        #endregion


    }
}
